﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Web;

using ClassModel;
using ClassCommon;


namespace ClassDAL
{
    public class t_class_CreateTxt_DAL
    {
        /// <summary>
        /// 4个空格的分隔符TAB
        /// </summary>
        private const string SPACE_SPILT = "    ";
        /// <summary>
        /// 根据taskid创建txt文件
        /// </summary>
        /// <param name="taskid"></param>
        public static string createDataTxt(int taskid, int userid)
        {

            StringBuilder dataTxtBuilder = new StringBuilder();

            #region 第一行数据
            // 第一行数据
            //10(班级数量) 12(科目数量) 5(一周上课天数) 4(上午节次) 3(下午节次)

            // 获得上传文件
            t_class_fileupload fileupload = t_class_user_fileupalod_DAL.GetExcelFileWithTaskId(taskid, userid);
            if (fileupload == null) throw new ArgumentException("当前任务不存在对应关系的上传excel文件!");
            // 基本信息，是data.txt 文件的第一行数据
            StringBuilder basicInfoBuilder = new StringBuilder();

            // 根据fileupload的文件id，获取老师、课程、班级
            // 获取班级数量
            int classCount = t_class_class_DAL.GetClassCountWithFileId(fileupload.id);
            basicInfoBuilder.Append(classCount.ToString("d") + SPACE_SPILT);

            // 获取课程数量
            int courseCount = t_class_course_DAL.getCourseCountWithFileId(fileupload.id);
            basicInfoBuilder.Append(courseCount.ToString("d") + SPACE_SPILT);
            // 
            t_class_sections section = t_class_sections_DAL.GetSectionByTaskID(taskid);
            int daysOfweek = section.dayOfWeek;// 一周多少天课
            int amLessionCount = section.AMSections;// 上午几节
            int pmLessionCount = section.PMSections;// 下午几节
            int totalLessionCount = amLessionCount + pmLessionCount; // 一天一共几节课
            basicInfoBuilder.Append(daysOfweek.ToString("d") + SPACE_SPILT);
            basicInfoBuilder.Append(amLessionCount.ToString("d") + SPACE_SPILT);
            basicInfoBuilder.Append(pmLessionCount.ToString("d") + SPACE_SPILT);
            // basicInfoBuilder.Append("\n");


            // 获得老师的数量 - 加载第一行最后
            int teacherCount = t_class_teacher_DAL.GetTeacherCountWithField(fileupload.id);
            basicInfoBuilder.Append(teacherCount.ToString("d") + SPACE_SPILT);

            // 第一行数据解析完毕
            dataTxtBuilder.AppendLine(basicInfoBuilder.ToString());
            #endregion

            #region 按老师班级以及课程的关系分布数据 - 第二块
            // 第二块，按班级解析数据
            /*
             6(第一个班第一门课一周上6节)	1(一次连堂课，2节)	1(老师编号)	6(第二门课一周6节)	1	7	6	1	13	1	0	18	1	0	19	2	0	22	1	0	24	
             */

            // 根据fileid获取excel的班级老师排课的信息
            List<t_class_schedule> scheduleList = t_class_schedule_DAL.GetScheduleDataWithFileId(fileupload.id);
            if (scheduleList == null) throw new ArgumentException(string.Format("文件编号为:{0} 的excel，并没有提取出老师、课程、班级的上课关系数据       查看SQL语句： select * from t_class_schedule where fileid = {1};", fileupload.id));

            StringBuilder classScheduleBuilder = new StringBuilder();
            // 获得所有班级的数据
            var classesList = t_class_class_DAL.GetClassListWithFileId(fileupload.id);
            for (int cc = 0; cc < classesList.Count; cc++)
            {
                // 当前班级排课信息
                var currentClassChedueInfoList = scheduleList.Where(sche => sche.classid == classesList[cc].id).ToList();
                // 一个班级一行，每门课程是  
                string dataInfo = string.Empty;
                currentClassChedueInfoList.ForEach(cls =>
                {
                    // 6(第一个班第一门课一周上6节)	1(一次连堂课，2节)	1(老师编号)
                    int teacherid = cls.teacherid;//老师id
                    // 获得老师对应的算法需要的dataTxtId
                    int dataTxtId = t_class_teacher_DAL.GetTeacherInfoById(teacherid).dataTxtid;

                    int hasLT = 0; // 是否有连堂课
                    int totalLessonCount = 0;// 一周几节课
                    if (!cls.condition.Contains("+"))
                    {
                        // 没有连堂课    
                        hasLT = 0;
                        totalLessonCount = Convert.ToInt32(cls.condition);
                    }
                    else
                    {
                        string[] arr = cls.condition.Split(new char[] { '+' });
                        int num1 = Convert.ToInt32(arr[0]);
                        int num2 = Convert.ToInt32(arr[1]);
                        totalLessonCount = num1 + num2 + 1; // 3 + 1 等于3节课 + 1次连堂课 = 3 + 1 + 1  = 5
                        hasLT = 1;
                    }

                    dataInfo += totalLessonCount.ToString("d") + SPACE_SPILT + hasLT.ToString("d") + SPACE_SPILT + dataTxtId.ToString("d") + SPACE_SPILT;
                });

                classScheduleBuilder.AppendLine(dataInfo);
            }

            // 第二块数据解析完毕。
            dataTxtBuilder.Append(classScheduleBuilder.ToString());
            #endregion

            #region 课程的不排课数据
            // 第三块数据 每门课程排课规则。
            /**
                1(第一门课排课规则)
        (星期一)1	1	1	1	1	0	0	0
                1	1	1	1	1	0	0	0
                1	1	1	1	1	0	0	0
                1	1	1	1	1	0	0	0
                1	1	1	1	1	0	0	0
             */


            // 获得当前excel文件里的所有课程。
            var allCourses = t_class_course_DAL.GetCourseListWithFileID(fileupload.id);
            // 获得当前excel文件下的设定的全部不排课的课程。
            var courseNoScheList = t_ClassTeacherCourse_NoSchedule_DAL.GetNoScheduleWithTaskid(taskid, ConfigSetting.NoScheduleCourseType);
            StringBuilder courseScheduleBuilder = new StringBuilder(); // 课程排课的builder
            for (int a = 0; a < allCourses.Count; a++)
            {
                var currentCourse = allCourses[a];
                // 当前课程的datatxtid
                courseScheduleBuilder.AppendLine(currentCourse.dataTxtid.ToString("d")); // 1

                // 获得当前课程的不排课记录
                var currentCourseNoScheModel = courseNoScheList.Where(c => c.dataid == currentCourse.id).FirstOrDefault();

                if (currentCourseNoScheModel == null)
                {
                    // 课程没有设置不排课的约束
                    for (int dow = 1; dow <= daysOfweek; dow++)
                    {
                        string aDay = string.Empty;
                        for (int s = 1; s <= totalLessionCount; s++)
                        {
                            int num = 1;
                            aDay += num.ToString("d") + SPACE_SPILT;
                        }
                        courseScheduleBuilder.AppendLine(aDay);
                    }
                }
                else // 当前课程设置了不排课
                {
                    courseScheduleBuilder.Append(GetNoScheduleRect(currentCourseNoScheModel, totalLessionCount, daysOfweek));
                }
            }

            dataTxtBuilder.Append(courseScheduleBuilder.ToString());
            #endregion

            #region 老师的不排课数据

            // 获得当前excel文件里的所有的老师。
            var allTeachers = t_class_teacher_DAL.GetTeacherListWithFileId(fileupload.id);
            // 获得当前excel文件下的设定的全部不排课的老师。
            var teacherNoScheList = t_ClassTeacherCourse_NoSchedule_DAL.GetNoScheduleWithTaskid(taskid, ConfigSetting.NoScheduleTeacher);
            StringBuilder teacherScheduleBuilder = new StringBuilder(); // 老师的不排课builder
            for (int a = 0; a < allTeachers.Count; a++)
            {
                var currentTeacher = allTeachers[a];
                // 当前老师的datatxtid
                teacherScheduleBuilder.AppendLine(currentTeacher.dataTxtid.ToString()); // 1

                // 获得当前老师的不排课记录
                var currentTeacherNoScheModel = teacherNoScheList.Where(c => c.dataid == currentTeacher.id).FirstOrDefault();

                int aday = 1;

                if (currentTeacherNoScheModel == null)
                {
                    // 老师没有设置不排课的约束
                    for (int dow = 1; dow <= daysOfweek; dow++)
                    {
                        string aDay = string.Empty;
                        for (int s = 1; s <= totalLessionCount; s++)
                        {
                            // aDay += "1" + SPACE_SPILT;
                            aDay += aday.ToString("d") + SPACE_SPILT;
                        }
                        teacherScheduleBuilder.AppendLine(aDay);
                    }
                }
                else // 当老师程设置了不排课
                {
                    teacherScheduleBuilder.Append(GetNoScheduleRect(currentTeacherNoScheModel, totalLessionCount, daysOfweek));
                }
            }

            dataTxtBuilder.Append(teacherScheduleBuilder.ToString());

            #endregion

            #region 班级的不排课数据


            // 获得当前excel文件里的所有的班级。
            var allClasses = t_class_class_DAL.GetClassListWithFileId(fileupload.id);
            // 获得当前excel文件下的设定的全部不排课的班级。
            var classNoScheList = t_ClassTeacherCourse_NoSchedule_DAL.GetNoScheduleWithTaskid(taskid, ConfigSetting.NoScheduleClassType);
            StringBuilder classesScheduleBuilder = new StringBuilder(); // 班级的不排课builder
            for (int a = 0; a < allClasses.Count; a++)
            {
                var currentClass = allClasses[a];
                // 当前班级的datatxtid
                classesScheduleBuilder.AppendLine(currentClass.dataTxtid.ToString()); // 1

                // 获得当前班级的不排课记录
                var currentClassNoScheModel = classNoScheList.Where(c => c.dataid == currentClass.id).FirstOrDefault();

                int aday = 1;

                if (currentClassNoScheModel == null)
                {
                    // 老师没有设置不排课的约束
                    for (int dow = 1; dow <= daysOfweek; dow++)
                    {
                        string aDay = string.Empty;
                        for (int s = 1; s <= totalLessionCount; s++)
                        {
                            // aDay += "1" + SPACE_SPILT;
                            aDay += aday.ToString("d") + SPACE_SPILT;
                        }
                        classesScheduleBuilder.AppendLine(aDay);
                    }
                }
                else // 当老师程设置了不排课
                {
                    classesScheduleBuilder.Append(GetNoScheduleRect(currentClassNoScheModel, totalLessionCount, daysOfweek));
                }
            }

            dataTxtBuilder.Append(classesScheduleBuilder.ToString());

            #endregion

            #region 合班

            /**
             合班的数据结构
             * 3（三条合班记录）
             * 6（第六门课） 3（班级个数） 1 （班级编号） 2（班级编号） 3（班级编号）    
             * 2018年4月18日 把合班的js页面数据回传和数据存储以及生成data.txt的后台逻辑写完。
             */

            // 1. 获得合班信息
            var mergeList = t_class_merge_DAL.GetMergeListWithTaskId(taskid);
            if (mergeList != null && mergeList.Count > 0)
            {
                StringBuilder mergeBuilder = new StringBuilder();
                // 合班文本块和上面有两行换行
                //mergeBuilder.AppendLine("");
                //mergeBuilder.AppendLine("");
                mergeBuilder.Append("\r\n\r\n");
                // 合班的数量
                var mergeCount = mergeList.Count;
                mergeBuilder.AppendLine(mergeCount.ToString());// 3 条合班记录

                mergeList.ForEach(m =>
                {
                    // 
                    string lineStr = "";
                    var course = t_class_course_DAL.GetCourseById(m.courseid);
                    //第几门课，当前课程对应的 dataTxtID
                    lineStr += course.dataTxtid.ToString("d") + SPACE_SPILT; // 第六门课
                    lineStr += m.classCount.ToString("d") + SPACE_SPILT; //合班数量

                    // 班级编号
                    var classIDArrList = m.classIds.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList();
                    classIDArrList.ForEach(cid =>
                    {
                        // 拿到班级编号，还要拿到对应的datatxtId
                        var classDataTxtId = t_class_class_DAL.GetClassInfoById(Convert.ToInt32(cid)).dataTxtid;
                        lineStr += classDataTxtId.ToString("d") + SPACE_SPILT;
                    });

                    mergeBuilder.AppendLine(lineStr);
                });


                dataTxtBuilder.Append(mergeBuilder.ToString());
            }

            #endregion


            // 老师、课程、班级匹配
            StringBuilder dataMatchBuilder = new StringBuilder();

            #region 老师和datatxtid对应关系

            allTeachers.ForEach(teacher =>
            {
                // 老师编号  老师姓名
                dataMatchBuilder.AppendLine(teacher.teacher + SPACE_SPILT + teacher.dataTxtid.ToString("d"));
            });

            #endregion

            string dirName = string.Format("{0}_{1}_{2}", userid.ToString(), taskid.ToString(), EncryptHelper.Encrypt(taskid.ToString()));
            string dirPath = HttpContext.Current.Server.MapPath(string.Format("/dataTxt/{0}/", dirName));
            if (!Directory.Exists(dirPath))
            {
                Directory.CreateDirectory(dirPath);
            }

            #region teacher.txt文件创建
            string teacherFileName = string.Format("{0}_{1}_teacherInfo.txt", userid.ToString(), taskid.ToString());
            string teacherSavePath = string.Format("{0}\\{1}", dirPath, teacherFileName);
            using (StreamWriter teacherWriter = new StreamWriter(teacherSavePath, false, Encoding.UTF8))
            {
                teacherWriter.Write(dataMatchBuilder.ToString());
            }
            #endregion

            #region 文件data.txt创建
            string txtFileName = string.Format("{0}_{1}_datatxt.txt", userid.ToString(), taskid.ToString());
            string savePath = string.Format("{0}\\{1}", dirPath, txtFileName);
            using (StreamWriter sw = new StreamWriter(savePath, false, Encoding.ASCII)) // 转换编码格式  Encoding.UTF8 -> Encoding.ASCII
            {

                sw.Write(dataTxtBuilder.ToString());
            }
            #endregion

            return dataTxtBuilder.ToString();
        }

        /// <summary>
        /// 根据不排课数据，返回不排课矩阵
        /// </summary>
        /// <param name="noSchedule">老师、课程、班级不排课数据</param>
        /// <param name="cols">几列 --> 对应一周上几天课</param>
        /// <param name="days">几行 --> 对应一周上几天</param>
        /// <returns></returns>
        private static string GetNoScheduleRect(t_ClassTeacherCourse_NoSchedule noSchedule, int cols, int days)
        {
            // 2	1	1	1_1_0,1_2_0	course	2018-04-17 11:03:39.413

            StringBuilder rectBuilder = new StringBuilder();
            /*1_1,1_2*/
            string noSheduleStr = noSchedule.data.Replace("_0", string.Empty);
            string[] nsArr = noSheduleStr.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            int num1 = 0;
            int num2 = 1;
            for (int d = 1; d <= days; d++)
            {
                string line = string.Empty;
                for (int c = 1; c <= cols; c++)
                {
                    string placeHoder = string.Format("{0}_{1}", c, d);
                    if (nsArr.Contains(placeHoder))
                    {

                        line += num1.ToString("d") + SPACE_SPILT;
                    }
                    else
                    {

                        line += num2.ToString("d") + SPACE_SPILT;
                    }
                }
                rectBuilder.AppendLine(line);
            }

            return rectBuilder.ToString();
        }
    }
}
